﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.XPath;
using System.Xml.Linq;
using IRDev.Library.ExpandedException.Factory;

namespace AutoDeploy.Common.Library
{
    /// <summary>
    /// Mark Rowe markwrowe@hotmail.com  http://everythingworkflow.spaces.live.com  ,  Daniel Turnell daniel.turnell@gmail.com
    /// This Project http://autodeploy.codeplex.com
    /// </summary>
    public static class DeployHelper
    {
        /// <summary>
        /// GetDeploymentObjectNames returns all the names of Deployment objects in a autodeploy.xml file.
        ///   <DeploymentObject name="ESBToolKitRemote">
        /// </summary>
        /// <param name="xConfiguration">The configuration as an XDocument</param>
        /// <returns></returns>
        public static List<string> GetDeploymentObjectNames(this XDocument xConfiguration)
        {
            //Params
            List<string> Params = new List<string>();
            Params.Add(string.Format("String  x:{0}", xConfiguration.ToString()));
            try
            {
                List<string> ls = new List<string>();
                foreach (XElement xe in xConfiguration.Element("AutoDeploy").Elements("DeploymentObject"))
                {
                    ls.Add(xe.Attribute("name").Value);
                }
                return ls;
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "GetDeploymentObjectNames");
                throw ee;
            }
        }
        /// <summary>
        /// Get all CommandSets within a DeploymentObject
        /// </summary>
        /// <param name="deploymentObject">This will retrieve all the Command Sets</param>
        /// <returns></returns>
        public static List<CommandSet> GetCommandSets(this DeploymentObject deploymentObject)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("DeploymentObject  ado:{0}", deploymentObject.ToString()));
            try
            {
                var query = from c in deploymentObject.CommandSets
                            select c;
                return query.ToList();
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "GetCommandSets");
                throw ee;
            }
        }
        /// <summary>
        /// GetDeploymentObjectNames returns all the names of Deployment objects in a autodeploy.xml file.
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static List<string> GetDeploymentObjectNames(this string uri)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("String uri:{0}", uri));
            try
            {
                XDocument x = XDocument.Load(uri);
                return GetDeploymentObjectNames(x);
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "GetDeploymentObjectNames");
                throw ee;
            }
        }
        /// <summary>
        /// LoadDeploymentObjectFromAutoDeployConfig
        /// </summary>
        /// <param name="autodeployXmlURI"></param>
        /// <param name="deploymentObjectName"></param>
        /// <returns></returns>
        public static DeploymentObject LoadDeploymentObjectFromAutoDeployConfig(this string autodeployXmlURI, string deploymentObjectName)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("String autodeployXmlURI:{0}", autodeployXmlURI));
            Params.Add(string.Format("String deploymentObjectName:{0}", deploymentObjectName));
            try
            {
                return LoadDeploymentObjectFromAutoDeployConfig(GetDeploymentObject(autodeployXmlURI, deploymentObjectName));
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "LoadDeploymentObjectFromAutoDeployConfig");
                throw ee;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="currentDeployment"></param>
        /// <returns></returns>
        public static DeploymentObject LoadDeploymentObjectFromAutoDeployConfig(this XElement currentDeployment)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("XElement currentDeployment:{0}", currentDeployment.ToString()));
            try
            {
                return DeploymentObjectFactory(currentDeployment);
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "LoadDeploymentObjectFromAutoDeployConfig");
                throw ee;
            }
        }
        /// <summary>
        /// GetDeploymentObject
        /// </summary>
        /// <param name="autodeployXmlURI">Location of the autodeploy.xml configuration file.</param>
        /// <param name="deploymentObjectName">Grab an entire Deployment Object Element from the configuration file by name.  <DeploymentObject name="ESBToolKitRemote"></param>
        /// <returns></returns>
        public static XElement GetDeploymentObject(this string autodeployXmlURI, string deploymentObjectName)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("XElement autodeployXmlURI:{0}", autodeployXmlURI));
            Params.Add(string.Format("XElement deploymentObjectName:{0}", deploymentObjectName));
            try
            {
                XDocument xdoc = XDocument.Load(autodeployXmlURI);
                return xdoc.Element("AutoDeploy").Elements("DeploymentObject").Where(x => x.Attribute("name").Value.Trim() == deploymentObjectName.Trim()).FirstOrDefault();
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "GetDeploymentObject");
                throw ee;
            }
        }
        /// <summary>
        ///Command – doesRegistryEntryExist – to see if a registry entry exists (example:SOFTWARE/Microsoft/UDDI)
        ///Command – isInstalled – to see if they have the proper installations (example:SQL Server)
        ///Command – isServiceInstalled - to see if they have the proper service installed (example:IISADMIN)
        ///Command - Message
        ///Command - runCommandLine (EXE, COM, PS1, EXE, MSI, ZIP/UNZIP, Copy Move, Mappings can all be done here.)
        ///Command - runSQLCommand (Run Command From XML Config)
        ///Command - runSQLScript (SQL in file)
        ///Command - runIfServiceExists
        ///Command - runIfProgramInstalled
        ///Command - runIfRegistryExists
        ///Command - addXElement
        ///Command - replaceOrAddXElementIfMissing
        ///Command - replaceOrAddXAttributeIfMissing
        /// </summary>
        /// <param name="commandSet">A Single Command Set</param>
        /// <param name="runAsUserName">If this command needs user info, fill it out here.</param>
        /// <param name="runAsPassword">If this command needs password info, fill it out here.</param>
        /// <param name="sqlConnectionString">If this command needs a different password than the default Deployment Objects default. Then enter it here. </param>
        /// <returns></returns>
        public static string RunCurrentCommand(this CommandSet commandSet, string runAsUserName, string runAsPassword, string sqlConnectionString)
        {
            List<string> Params = new List<string>();
            Params.Add(string.Format("CommandSet cs:{0}", commandSet.ToString()));
            Params.Add(string.Format("String runAsUserName:{0}", runAsUserName));
            Params.Add(string.Format("String runAsPassword:{0}", runAsPassword));
            Params.Add(string.Format("String sqlConnectionString:{0}", sqlConnectionString));
            try
            {
                string s = string.Empty;
                bool found = false;
                List<string> ls = new List<string>();
                switch (commandSet.Command.ToLower().Trim())
                {
                    //Command – isInstalled – to see if they have the proper installations (example:SQL Server)
                    case "isinstalled":
                        {
                            found = false;
                            foreach (string value in commandSet.Values)
                            {
                                if (value.Contains("::"))
                                {
                                    if (ExternalHelper.isInstalled(value.Substring(0, value.IndexOf("::")).Trim(), bool.Parse((value.Substring(value.IndexOf("::") + 2).Trim()))))
                                    {
                                        s += "Passed:" + value.Substring(0, value.IndexOf("::")).Trim() + " Found." + commandSet.Success + "\n";
                                        found = true;
                                    }
                                }
                                else
                                {
                                    if (ExternalHelper.isInstalled(value, false))
                                    {
                                        s += "Passed:" + value.Substring(0, value.IndexOf("::")).Trim() + " Found." + commandSet.Success + "\n";
                                        found = true;
                                    }
                                }
                            }
                            if (!found)
                            {
                                s = "Error:" + commandSet.Error + "\n";
                            }
                            break;
                        }
                    case "doesFileExist":
                        {
                            found = false;
                            foreach (string value in commandSet.Values)
                            {
                                if (ExternalHelper.FileExists(commandSet.Values[0]))
                                {
                                    s += "Passed:" + commandSet.Values[0].Trim() + " Found." + commandSet.Success + "\n";
                                    found = true;
                                }
                            }
                            if (!found)
                            {
                                s = "Error:" + commandSet.Error + "\n";
                            }
                            break;
                        }
                    case "doesDirectoryExist":
                        {

                            found = false;
                            foreach (string value in commandSet.Values)
                            {
                                    if (ExternalHelper.DirectoryExists(commandSet.Values[0]))
                                    {
                                        s += "Passed:" + commandSet.Values[0].Trim() + " Found." + commandSet.Success + "\n";
                                        found = true;
                                    }
                            }
                            if (!found)
                            {
                                s = "Error:" + commandSet.Error + "\n";
                            }
                            break;
                        }
                    //Command – isServiceInstalled - to see if they have the proper service installed (example:IISADMIN)
                    case "isserviceinstalled":
                        {
                            found = false;
                            foreach (string value in commandSet.Values)
                            {
                                if (value.Contains("::"))
                                {
                                    if (ExternalHelper.isServiceInstalled(value.Substring(0, value.IndexOf("::")).Trim(), bool.Parse((value.Substring(value.IndexOf("::") + 2).Trim()))))
                                    {
                                        s += "Passed:" + value.Substring(0, value.IndexOf("::")).Trim() + " Found." + commandSet.Success + "\n";
                                        found = true;
                                    }
                                }
                                else
                                {
                                    if (ExternalHelper.isServiceInstalled(value, false))
                                    {
                                        s += "Passed:" + value.Substring(0, value.IndexOf("::")).Trim() + " Found." + commandSet.Success + "\n";
                                        found = true;
                                    }
                                }
                            }
                            if (!found)
                            {
                                s = "Error:" + commandSet.Error + "\n";
                            }
                            break;
                        }
                    //Command – doesRegistryEntryExist – to see if a registry entry exists (example:SOFTWARE/Microsoft/UDDI)
                    case "doesregistryentryexist":
                        {
                            s = commandSet.Values[0] + (ExternalHelper.registryEntryExistsInLocalMachine(commandSet.Values[0]) ? "" : "");
                            break;
                        }
                    //Command - Message
                    case "message":
                        {
                            s = StringHelper.ListOfStringToString(commandSet.Values, true);
                            break;
                        }
                    //Command - runSQLCommand (Run Command From XML Config)
                    case "runcommandline":
                        {
                            string imitate = (commandSet.Values.Count == 2 ? commandSet.Values[1] : "false");
                            if (commandSet.Values.Count > 1)
                            {
                                s = string.Format("Running Command Line:{0} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0]);
                                RunShellCommandChooser(commandSet.Values[0], runAsUserName, runAsPassword, imitate);
                            }
                            else
                            {
                                s = string.Format("Running Command Line:{0} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0]);
                                RunShellCommandChooser(commandSet.Values[0], runAsUserName, runAsPassword, "false");
                            }
                            break;
                        }
                    //Command - runSQLScript (SQL in file)
                    case "runsqlscript":
                        {
                            string sqlCommand = ExternalHelper.ReadAFile(commandSet.Values[0]);
                            string sqlConnString = (commandSet.Values.Count == 1 ? sqlConnectionString : commandSet.Values[1]);
                            s = string.Format("Running SQL Command {0} Using Connection:{1}", sqlCommand, sqlConnString);
#if DEBUG
#else
                        ExternalHelper.RunSqlCommand(sqlCommand, sqlConnString);
#endif
                            break;
                        }
                    //Command - runSQLCommand (Run Command From XML Config)
                    case "runsqlcommand":
                        {
                            string sqlCommand = commandSet.Values[0];
                            string sqlConnString = (commandSet.Values.Count == 1 ? sqlConnectionString : commandSet.Values[1]);
                            s = string.Format("Running SQL Command {0} Using Connection:{1}", commandSet.Values[0], (commandSet.Values.Count == 1 ? sqlConnectionString : commandSet.Values[1]));
#if DEBUG
#else
                        ExternalHelper.RunSqlCommand(sqlCommand, sqlConnString);
#endif
                            break;
                        }
                    //Command - runIfServiceExists
                    case "runifserviceexists":
                        {
                            string imitate = (commandSet.Values.Count == 3 ? commandSet.Values[2] : "false");
                            if (commandSet.Values.Count == 2 || commandSet.Values.Count == 3)
                            {
                                if (commandSet.Values[0].Contains("::"))
                                {
                                    if (ExternalHelper.isServiceInstalled(commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim(), bool.Parse((commandSet.Values[0].Substring(commandSet.Values[0].IndexOf("::") + 2).Trim()))))
                                    {
                                        RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                        s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim(), commandSet.Values[1]);
                                    }
                                    else
                                    {
                                        s = string.Format("Service Not Found: {0}" + commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim());
                                    }
                                }
                                else
                                {
                                    if (ExternalHelper.isServiceInstalled(commandSet.Values[0].Trim(), false))
                                    {
                                        RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                        s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Trim(), commandSet.Values[1]);
                                    }
                                    else
                                    {
                                        s = string.Format("Service Not Found: {0}", commandSet.Values[0].Trim());
                                    }
                                }
                            }
                            else
                            {
                                s = string.Format("runIfServiceExists takes 2 to 3 values\nYou have {0}", (commandSet.Values.Count));
                            }
                            break;
                        }
                    //Command ID
                    case "runiffileexists":
                        {
                            string imitate = (commandSet.Values.Count == 3 ? commandSet.Values[2] : "false");
                            if (ExternalHelper.FileExists(commandSet.Values[0]))
                            {
                                RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Trim(), commandSet.Values[1]);
                            }
                            else
                            {
                                s = string.Format("File Not Found: {0}", commandSet.Values[0].Trim());
                            }
                            break;
                        }
                    //Command - runIfProgramInstalled
                    case "runifprograminstalled":
                        {
                            string imitate = (commandSet.Values.Count == 3 ? commandSet.Values[2] : "false");
                            if (commandSet.Values.Count == 2 || commandSet.Values.Count == 3)
                            {
                                if (commandSet.Values[0].Contains("::"))
                                {
                                    if (ExternalHelper.isInstalled(commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim(), bool.Parse((commandSet.Values[0].Substring(commandSet.Values[0].IndexOf("::") + 2).Trim()))))
                                    {
                                        RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                        s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim(), commandSet.Values[1]);
                                    }
                                    else
                                    {
                                        s = "Program Not Found:" + commandSet.Values[0].Substring(0, commandSet.Values[0].IndexOf("::")).Trim();
                                    }
                                }
                                else
                                {
                                    if (ExternalHelper.isInstalled(commandSet.Values[0].Trim(), false))
                                    {
                                        RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                        s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Trim(), commandSet.Values[1]);
                                    }
                                    else
                                    {
                                        s = "Program Not Found:" + commandSet.Values[0].Trim();
                                    }
                                }
                            }
                            else
                            {
                                s = string.Format("runIfServiceExists takes 2 to 3 values\nYou have {0}", (commandSet.Values.Count));
                            }
                            break;
                        }
                    //Command - runIfRegistryExists
                    case "runifregistryexists":
                        {
                            string imitate = (commandSet.Values.Count == 3 ? commandSet.Values[2] : "false");
                            if (ExternalHelper.registryEntryExistsInLocalMachine(commandSet.Values[0].Trim()))
                            {
                                RunShellCommandChooser(commandSet.Values[1], runAsUserName, runAsPassword, imitate);
                                s = string.Format("{0} was found.\nRunning Command Line:{1} You will need to check your own command window. This is UNMANAGED", commandSet.Values[0].Trim(), commandSet.Values[1]);
                            }
                            else
                            {
                                s = string.Format("Registry Entry Not Found: {0}", commandSet.Values[0].Trim());
                            }
                            break;
                        }
                    //Command - addXElement
                    case "addxelement":
                        {
                            List<string> l = new List<string>();
                            if (commandSet.Values.Count >= 3)
                            {
                                s = string.Format("Adding XElement[{0}] to File:{1}", commandSet.Values[1], commandSet.Values[0]);
                                for (int i = 3; i < commandSet.Values.Count; i++)
                                {
                                    ls.Add(commandSet.Values[i]);
                                }
                                s = XPathHelper.AddElementFromXPath(commandSet.Values[0], commandSet.Values[1], commandSet.Values[2], l);
                                ExternalHelper.WriteAFile(s,commandSet.Values[0], false);

                            }
                            else
                            {
                                string.Format("addXElement requires at least 3 parameters you supplied {0}.\n\t1.File Name\n\t2.XPath\n\t3.ElementToAdd In string format.\n\t 4+.(Optional) Namespace using Prefix::URN format", commandSet.Values.Count);
                            }
                            break;
                        }
                    //Command - replaceOrAddXElementIfMissing
                    case "replaceoraddxelementifmissing":
                        {
                            List<string> l = new List<string>();
                            if (commandSet.Values.Count >= 3)
                            {
                                s = string.Format("Adding/Editing XElement[{0}] to File:{1}", commandSet.Values[1], commandSet.Values[0]);
                                for (int i = 3; i < commandSet.Values.Count; i++)
                                {
                                    ls.Add(commandSet.Values[i]);
                                }
                                s = XPathHelper.ReplaceOrAddIfMissingElementInElementUsingXPath(commandSet.Values[0], commandSet.Values[1], commandSet.Values[2], l);
                                ExternalHelper.WriteAFile(s, commandSet.Values[0], false);

                            }
                            else
                            {
                                string.Format("addXElement requires at least 3 parameters you supplied {0}.\n\t1.File Name\n\t2.XPath\n\t3.ElementToAdd In string format.\n\t 4+.(Optional) Namespace using Prefix::URN format", commandSet.Values.Count);
                            }
                            break;
                        }
                    //Command - replaceOrAddXAttributeIfMissing
                    case "replaceoraddxattributeifmissing":
                        {
                            List<string> l = new List<string>();
                            if (commandSet.Values.Count >= 3)
                            {
                                s = string.Format("Adding/Editing Attribute [{0}] to File:{1}", commandSet.Values[1], commandSet.Values[0]);
                                for (int i = 3; i < commandSet.Values.Count; i++)
                                {
                                    ls.Add(commandSet.Values[i]);
                                }
                                XElement xe = XElement.Load(commandSet.Values[0]);
                                s = XPathHelper.EditAttributeInXPath(commandSet.Values[0], commandSet.Values[1], commandSet.Values[2], l);
                            #if DEBUG
                            #else                          
                            ExternalHelper.WriteAFile(s,cs.Values[0], false);
#endif
                            }
                            else
                            {
                                string.Format("addXElement requires at least 3 parameters you supplied {0}.\n\t1.File Name\n\t2.XPath\n\t3.ElementToAdd In string format.\n\t 4+.(Optional) Namespace using Prefix::URN format", commandSet.Values.Count);
                            }
                            break;
                        }
                }
                return s;
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "RunCurrentCommand");
                throw ee;
            }
        }
        /// <summary>
        /// Shells out to command.
        /// </summary>
        /// <param name="commandLine">The command line to run.</param>
        /// <param name="runAsUserName">If the command needs to impersonate a user enter the domain\user in the configuration. </param>
        /// <param name="runAsPassword">If the command needs to impersonate a user enter the password in the configuration.</param>
        /// <param name="imitate">String of "true" or "false" if you want to imitate.</param>
        private static void RunShellCommandChooser(string commandLine, string runAsUserName, string runAsPassword, string imitate)
        {
            //Params
            List<string> Params = new List<string>();
            Params.Add(string.Format("String commandLine:{0}", commandLine));
            Params.Add(string.Format("String runAsUserName:{0}", runAsUserName));
            Params.Add(string.Format("String runAsPassword:{0}", runAsPassword));
            Params.Add(string.Format("String imitate:{0}", imitate));
            #if DEBUG
            #else
            try{
            //If Run As Current User
            bool runAsOtherUser = false;
            if (string.IsNullOrEmpty(runAsUserName) || string.IsNullOrEmpty(runAsPassword) || !bool.TryParse(imitate, out runAsOtherUser))
            {   

                    ExternalHelper.RunShellCommand(commandLine);
            }
            else
            {
                if (runAsOtherUser)
                {
                    ExternalHelper.RunShellCommand(commandLine, runAsUserName, runAsPassword);

                }
                else
                {
                    ExternalHelper.RunShellCommand(commandLine);
                }
            }
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "RunShellCommandChooser");
                throw ee;
            }
#endif
        }
        /// <summary>
        ///  DeploymentObjectFactory
        ///  This returns a Deployment object loaded by a XElement Configuration File.
        /// </summary>
        /// <param name="xe">XElement representation of the AutoDeploy Configuration Deployment Object.</param>
        /// <returns></returns>
        public static DeploymentObject DeploymentObjectFactory(this XElement xe)
        {
            //Params
            List<string> Params = new List<string>();
            Params.Add(string.Format("XElement xe:{0}", xe.ToString()));
            try
            {
                DeploymentObject DeployThis = new DeploymentObject();
                DeployThis.is64Bit = System.Environment.Is64BitOperatingSystem;
                DeployThis.Name = xe.Attribute("name").Value;
                if (xe.Attribute("allowFastDeploy") != null)
                {
                    DeployThis.FastDeploy = bool.Parse(xe.Attribute("allowFastDeploy").Value);
                }
                List<string> Errors = new List<string>();
                CommandSet cs = new CommandSet();
                string file = string.Empty;
                foreach (XElement PreparedApp in xe.Elements("PrepareCommands").Elements("PreparedApp"))
                {
                    file = PreparedApp.Element("File").Value;
                    if (!ExternalHelper.DirectoryExists(file))
                    {
                        if (ExternalHelper.isFileInLocation(ref file))
                        {
                            DeployThis.PreparedApps.Add(PreparedApp.Element("Name").Value, file.Trim());
                        }
                        else
                        {
                            DeployThis.PreparedApps.Add(PreparedApp.Element("Name").Value, "Missing Value");
                        }
                    }
                    else
                    {

                        DeployThis.PreparedApps.Add(PreparedApp.Element("Name").Value, file.Trim());
                    }

                }
                //.OrderBy(x => x.Attribute("priority"))
                foreach (XElement commandSet in xe.Elements("Commands").Elements("CommandSet"))
                {
                    cs = new CommandSet();
                    if (commandSet.Element("Command").Value != null)
                    {
                        List<string> commandList = StringHelper.StringToListOfString(commandSet.Element("Command").Value, "::", true, true);
                        cs.Command = commandList[0];
                        if (commandList.Count > 1)
                        {
                            cs.CommandTrigger = commandList[1];
                        }
                    }
                    if (commandSet.Element("Part").Value != null)
                    {
                        List<string> partList = StringHelper.StringToListOfString(commandSet.Element("Part").Value, "::", true, true);
                        cs.Part = partList[0];
                        if (partList.Count > 1)
                        {
                            cs.PartTrigger = partList[1];
                        }
                    }
                    int i;
                    if (!Int32.TryParse(commandSet.Attribute("priority").Value, out i))
                    {
                        i = 0;
                    }
                    cs.Priority = ((commandSet.Attribute("priority") == null) ? 0 : Int32.Parse(commandSet.Attribute("priority").Value));
                    cs.Description = ((commandSet.Element("Description") == null) ? string.Empty : commandSet.Element("Description").Value);
                    cs.Error = ((commandSet.Element("Error") == null) ? string.Empty : commandSet.Element("Error").Value);
                    cs.Success = ((commandSet.Element("Success") == null) ? string.Empty : commandSet.Element("Success").Value);
                    foreach (XElement value in commandSet.Elements("Values").Elements("Value"))
                    {
                        Errors.Clear();
                        if (value != null)
                        {
                            cs.Values.Add(StringHelper.FormatAutoDeployValue(value.Value, DeployThis.PreparedApps, ref Errors));
                        }
                        foreach (string e in Errors)
                        {
                            DeployThis.Errors.Add(e);
                        }
                    }
                    DeployThis.CommandSets.Add(cs);
                }
                return DeployThis;
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "DeploymentObjectFactory");
                throw ee;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="deploymentObject"></param>
        /// <returns></returns>
        public static List<CommandValuesView> LoadCommandValuesView(this DeploymentObject deploymentObject)
        {
            //Params
            List<string> Params = new List<string>();
            Params.Add(string.Format("DeploymentObject ado:{0}", deploymentObject.ToString()));
            try
            {
                return (from cs in deploymentObject.CommandSets
                        from value in cs.Values
                        select new CommandValuesView()
                        {
                            Command = cs.Command,
                            Priority = cs.Priority,
                            Value = value,
                            Run = true
                        }).ToList();
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "LoadDeploymentObjectFromAutoDeployConfig");
                throw ee;
            }
        }
        public static bool ValidateDeploymentObject(ref DeploymentObject ado)
        {
            //Params
            List<string> Params = new List<string>();
            Params.Add(string.Format("DeploymentObject ado:{0}", ado.ToString()));
            try
            {
                ado.CommandSets.OrderBy(x => x.Priority);
                if (ado.CommandSets.Count != ado.CommandSets[ado.CommandSets.Count - 1].Priority)
                {
                    return false;
                }
                return true;
            }
            catch (IRDev.Library.ExpandedException.Common.ExpandedException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                IRDev.Library.ExpandedException.Common.ExpandedException ee = ex.CreateAndReturnExpandedException(StringHelper.ListOfStringToString(Params, true), "DeployHelper", "ValidateDeploymentObject");
                throw ee;
            }
        }
    }
}
